4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
16 namespace Microsoft
.JScript
{
19 A stack frame is used to avoid allocating the name lookup hash table until it is actually needed.
21 Rather than allocating the hash table directly and then duplicating code that already resides in JSObject and FunctionScope,
22 a FunctionScope is allocated and populated whenever the hashtable is needed for a name lookup.
25 using Microsoft
.JScript
.Vsa
;
27 using System
.Reflection
;
28 using System
.Collections
;
29 using System
.Diagnostics
;
31 public sealed class StackFrame
: ScriptObject
, IActivationObject
{
32 internal ArgumentsObject caller_arguments
;
33 private JSLocalField
[] fields
;
34 public Object
[] localVars
;
35 private FunctionScope nestedFunctionScope
;
36 internal Object thisObject
;
37 public Object closureInstance
;
39 internal StackFrame(ScriptObject parent
, JSLocalField
[] fields
, Object
[] local_vars
, Object thisObject
)
41 this.caller_arguments
= null;
43 this.localVars
= local_vars
;
44 this.nestedFunctionScope
= null;
45 this.thisObject
= thisObject
;
46 if (parent
is StackFrame
)
47 this.closureInstance
= ((StackFrame
)parent
).closureInstance
;
48 else if (parent
is JSObject
)
49 this.closureInstance
= parent
;
51 this.closureInstance
= null;
54 internal JSVariableField
AddNewField(String name
, Object
value, FieldAttributes attributeFlags
){
55 this.AllocateFunctionScope();
56 return this.nestedFunctionScope
.AddNewField(name
, value, attributeFlags
);
59 private void AllocateFunctionScope(){
60 if (this.nestedFunctionScope
!= null)
62 this.nestedFunctionScope
= new FunctionScope(this.parent
);
63 if (this.fields
!= null)
64 for (int i
= 0, n
= this.fields
.Length
; i
< n
; i
++)
65 this.nestedFunctionScope
.AddOuterScopeField(this.fields
[i
].Name
, this.fields
[i
]);
68 public Object
GetDefaultThisObject(){
69 ScriptObject parent
= this.GetParent();
70 IActivationObject iob
= parent
as IActivationObject
;
71 if (iob
!= null) return iob
.GetDefaultThisObject();
75 public FieldInfo
GetField(String name
, int lexLevel
){
79 public GlobalScope
GetGlobalScope(){
80 return ((IActivationObject
)this.GetParent()).GetGlobalScope();
83 FieldInfo IActivationObject
.GetLocalField(String name
){
84 this.AllocateFunctionScope();
85 return this.nestedFunctionScope
.GetLocalField(name
);
88 public override MemberInfo
[] GetMember(String name
, BindingFlags bindingAttr
){
89 this.AllocateFunctionScope();
90 return this.nestedFunctionScope
.GetMember(name
, bindingAttr
);
93 public override MemberInfo
[] GetMembers(BindingFlags bindingAttr
){
94 this.AllocateFunctionScope();
95 return this.nestedFunctionScope
.GetMembers(bindingAttr
);
98 internal override void GetPropertyEnumerator(ArrayList enums
, ArrayList objects
){
99 throw new JScriptException(JSError
.InternalError
);
103 [DebuggerStepThroughAttribute
]
104 [DebuggerHiddenAttribute
]
106 internal override Object
GetMemberValue(String name
){
107 this.AllocateFunctionScope();
108 return this.nestedFunctionScope
.GetMemberValue(name
);
112 [DebuggerStepThroughAttribute
]
113 [DebuggerHiddenAttribute
]
115 public Object
GetMemberValue(String name
, int lexlevel
){
117 return Missing
.Value
;
118 if (this.nestedFunctionScope
!= null)
119 return this.nestedFunctionScope
.GetMemberValue(name
, lexlevel
);
121 return ((IActivationObject
)this.parent
).GetMemberValue(name
, lexlevel
-1);
124 public static void PushStackFrameForStaticMethod(RuntimeTypeHandle thisclass
, JSLocalField
[] fields
, VsaEngine engine
){
125 PushStackFrameForMethod(Type
.GetTypeFromHandle(thisclass
), fields
, engine
);
128 public static void PushStackFrameForMethod(Object thisob
, JSLocalField
[] fields
, VsaEngine engine
){
129 Globals globals
= engine
.Globals
;
130 IActivationObject top
= (IActivationObject
)globals
.ScopeStack
.Peek();
131 String currentNamespace
= thisob
.GetType().Namespace
;
132 WithObject wob
= null;
133 if (currentNamespace
!= null && currentNamespace
.Length
> 0){
134 wob
= new WithObject(top
.GetGlobalScope(), new WrappedNamespace(currentNamespace
, engine
));
135 wob
.isKnownAtCompileTime
= true; //For use by an eval inside this method
136 wob
= new WithObject(wob
, thisob
);
138 wob
= new WithObject(top
.GetGlobalScope(), thisob
);
139 wob
.isKnownAtCompileTime
= true;
140 StackFrame sf
= new StackFrame(wob
, fields
, new Object
[fields
.Length
], thisob
);
141 sf
.closureInstance
= thisob
;
142 globals
.ScopeStack
.GuardedPush(sf
);
146 [DebuggerStepThroughAttribute
]
147 [DebuggerHiddenAttribute
]
149 internal override void SetMemberValue(String name
, Object
value){
150 this.AllocateFunctionScope();
151 this.nestedFunctionScope
.SetMemberValue(name
, value, this);